import { _decorator, Component, Node, v3, clamp } from 'cc';
import { GlobalEnum } from '../../../Init/Config/GlobalEnum';
import { GlobalTmpData } from '../../../Init/Config/GlobalTmpData';
import { EventTypes } from '../../../Init/Managers/EventTypes';
import { LevelDataTmp } from '../../../Init/SystemStorage/StorageTemp';
import GlobalPool from '../../../Init/Tools/GlobalPool';
import { BasicLayer } from '../Common/Basic/BasicLayer';
import { MappingZombie } from './MappingZombie';
const { ccclass, property } = _decorator;
/**3D场景下的角色管理 */
@ccclass('ZombieLayer')
export class ZombieLayer extends BasicLayer {
    private _zombieRecs: { [uuid: string]: MappingZombie } = {};
    private _isGameRun = false;
    private _homeRoleData: any[] = [];

    // #region -------------------------------层级生命周期------------
    /**初始化 只执行一次*/
    protected init() {

    };
    /**注册通过自定义事件管理器管理的事件  */
    protected onEvents() {
        this.on(EventTypes.Mapping3DEvents.SetRoles, this.onSetRoles, this);
        this.on(EventTypes.GameEvents.GameRun, this.onGameRun, this);
        this.on(EventTypes.RoleEvents.AddBuff, this.onAddBuff, this);
    };
    /**设置状态、数据等, */
    public setData(data?: LevelDataTmp) {

    };
    /**重置状态、数据等，子类实现 ,注销事件*/
    public reset() {
        this._isGameRun = false;
        this._homeRoleData = [];

        for (const key in this._zombieRecs) {
            const zb = this._zombieRecs[key];
            zb && zb.reset();
        }

        this._zombieRecs = {};
        this.resetBuff();
        GlobalPool.putAllChildren(this.node);
    }

    public customUpdate(dt: number) {
        const _cfg = GlobalTmpData.HpData;
        for (const key in this._zombieRecs) {
            const zombie = this._zombieRecs[key];
            if (zombie && zombie.node.active) {
                zombie.update(dt);
            } else {
                this._zombieRecs[key].reset();
                delete this._zombieRecs[key];
                _cfg[key].isShow = false;
            }
        }
        this.updateRoleHp(dt);
        this.updateBuff(dt);
    }

    public customLateUpdate(dt: number) {

    }

    // #endregion

    //#region -------------------------私有--------------
    private createRole(d, isBake = true) {
        let _name = isBake ? 'zombie3dBake' : 'zombie3dUnBake';
        let e = GlobalPool.get(_name); //zombie3dUnBake -动作融合 / zombie3dBake 动作烘焙
        e.setPosition(0, -10, 0);
        let cmp = new MappingZombie(e, d);
        cmp.init();
        e.parent = this.node;
        this._zombieRecs[e.uuid] = cmp;
        return cmp;
    }
    /**更新HP */
    protected updateRoleHp(dt) {
        if (!GlobalTmpData.Game.isGameRun) return;
        const _cfg = GlobalTmpData.HpData;
        for (const uuid in this._zombieRecs) {
            const role = this._zombieRecs[uuid];

            if (!_cfg[uuid]) {
                _cfg[uuid] = {
                    isShow: true, rate: 1, curRate: 1,
                    isPlayer: false, wpos: v3(),
                    countTime: 0, type: GlobalEnum.HpBarType.player,
                    isHide: false,
                };
            } else {
                const prop = role.mappingProps.node[GlobalEnum.ExtralProp.customProps];
                const curRate = prop.hp / prop.maxHp;
                if (_cfg[uuid].rate != curRate) {
                    _cfg[uuid].rate = curRate;
                    _cfg[uuid].countTime = 0;
                    _cfg[uuid].isShow = true;
                } else {
                    /**同样的数据超过1s之后不再显示 */
                    _cfg[uuid].countTime += dt;
                    if (_cfg[uuid].countTime >= 2) {
                        _cfg[uuid].isShow = false;
                    }
                }
                _cfg[uuid].isHide = prop.isHide;
                _cfg[uuid].wpos.set(role.node.worldPosition);
            }
        }

    }
    //#endregion

    //#region --------------------------事件-----------------
    //映射到3d
    protected onSetRoles(d) {
        this.createRole(d, GlobalTmpData.Game.isGameRun);
        this._homeRoleData.push(d);
    }

    protected onGameRun() {
        this._isGameRun = true;

        //正常关卡
        if (!GlobalTmpData.Game.isGuideLv) {
            //移除之前的模型
            for (const key in this._zombieRecs) {
                const rec = this._zombieRecs[key];
                rec.reset();
                GlobalPool.put(rec.node);
                delete this._zombieRecs[key];
            }

            for (let i = 0; i < this._homeRoleData.length; i++) {
                const d = this._homeRoleData[i];
                //切换成烘焙模型
                let cmp = this.createRole(d, true);
                cmp.curState = GlobalEnum.ZombieState.Born;
                if (cmp.mappingProps.state != GlobalEnum.ZombieState.Idle) {
                    cmp.anim.playAnim(GlobalEnum.ZombieClips.Crawl);
                }
            }
            this._homeRoleData = [];
        }
    }

    //#endregion

    //#region --------------------------buff-------------
    //buff记录
    private resetBuff() {
        GlobalTmpData.BuffRecs = {};
    }

    protected onAddBuff(d: { type: number, num: number, delay: number }) {
        if (!GlobalTmpData.BuffRecs[d.type]) {
            GlobalTmpData.BuffRecs[d.type] = { num: 0, curt: 0, delay: 0 };
        }
        GlobalTmpData.BuffRecs[d.type].num = d.num;
        GlobalTmpData.BuffRecs[d.type].delay = d.delay;
        GlobalTmpData.BuffRecs[d.type].curt = 0;
    }

    protected updateBuff(dt) {
        const cfg = GlobalTmpData.BuffRecs;
        for (const key in cfg) {
            const rec = cfg[key];
            if (rec.curt < rec.delay) {
                rec.curt += dt;
                rec.curt = clamp(rec.curt, 0, rec.delay);
                if (rec.curt == rec.delay) {
                    rec.num = 0;
                }
            }
        }
    }

    //#endregion
}

